package com.yaoguys.common.utils;

import java.util.*;

import com.yaoguys.common.enumeration.DefaultStr;

public class coding {

    private static int NumThresholdVal = 57;

    private static int CharMinThresholdVal = 122;

    private static int CharBigThresholdVal = 90;

    /**
     * 把字母的字串首字母大写
     * 
     * @param str
     * @return
     */
    public static String getFirstCapitl(String str) {
        String string = new String();
        if (str.matches("[A-Za-z]+")) {
            String firstLatter = str.toUpperCase().substring(0, 1);
            String lostLatter = str.substring(1, str.length());
            string = firstLatter + lostLatter;
        }
        return string;
    }

    /**
     * 驼峰式命名法
     */
    public static String toCamelCase(String s) {
        if (s == null) {
            return null;
        }
        s = s.toLowerCase();
        StringBuilder sb = new StringBuilder(s.length());
        boolean upperCase = false;
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);

            if (c == "_".charAt(0)) {
                upperCase = true;
            } else if (upperCase) {
                sb.append(Character.toUpperCase(c));
                upperCase = false;
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }

    /**
     * 下划线转驼峰命名
     */
    public static String toUnderScoreCase(String str) {
        if (str == null) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        // 前置字符是否大写
        boolean preCharIsUpperCase = true;
        // 当前字符是否大写
        boolean curreCharIsUpperCase = true;
        // 下一字符是否大写
        boolean nexteCharIsUpperCase = true;
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            if (i > 0) {
                preCharIsUpperCase = Character.isUpperCase(str.charAt(i - 1));
            } else {
                preCharIsUpperCase = false;
            }

            curreCharIsUpperCase = Character.isUpperCase(c);

            if (i < (str.length() - 1)) {
                nexteCharIsUpperCase = Character.isUpperCase(str.charAt(i + 1));
            }

            if (preCharIsUpperCase && curreCharIsUpperCase && !nexteCharIsUpperCase) {
                sb.append("_");
            } else if ((i != 0 && !preCharIsUpperCase) && curreCharIsUpperCase) {
                sb.append("_");
            }
            sb.append(Character.toLowerCase(c));
        }
        return sb.toString();
    }

    public static String getNextNumberByType(String testStr, DefaultStr charBig) {

        switch (charBig) {
            case CHAR_BIG:
                testStr = getCharBigNext(testStr);
                break;
            case CHAR_MIN:
                testStr = getCharMinNext(testStr);
                break;
            case SERIALNUMBER_BIG:
                testStr = getNumAndCharBig(testStr);
                break;
            case SERIALNUMBER_MIN:
                testStr = getNumAndCharMin(testStr);
                break;
            case CHAR_MIN_AND_BIG:
                testStr = getCharMinAndBig(testStr);
                break;
            case SERIALNUMBER:
                testStr = getNumAndCharMinAndBig(testStr);
                break;
            case NUM:
            default:
                testStr = getNumNext(testStr);
                break;
        }
        return testStr;
    }

    /**
     * 取得字串大小写的下个字串
     * 
     * @param charStr 循环字串
     * @return
     */
    private static String getCharMinAndBig(String charStr) {
        if (charStr == null) {
            return charStr;
        }
        char[] charArray = new StringBuffer(charStr).reverse().toString().toCharArray();
        boolean tempBtn = true;
        charStr = "";
        for (char str : charArray) {
            if (tempBtn) {
                String valueOf = String.valueOf(str);
                if (valueOf.matches("[a-z]+")) {
                    String charBigNext = getCharMinNext(valueOf);
                    if (!charBigNext.equals("a")) {
                        tempBtn = false;
                    } else {
                        charBigNext = "0";
                    }
                    charStr += charBigNext;
                } else if (valueOf.matches("[A-Z]+")) {
                    String charBigNext = getCharBigNext(valueOf);
                    if (charBigNext.equals("A")) {
                        charBigNext = "a";
                    }
                    tempBtn = false;
                    charStr += charBigNext;
                }
            } else {
                charStr += str;
            }
        }
        return new StringBuffer(charStr).reverse().toString();
    }

    /**
     * 取得字串数字与字母大小写的下个字串
     * 
     * @param charStr 循环字串
     * @return
     */
    private static String getNumAndCharMinAndBig(String charStr) {
        if (charStr == null) {
            return charStr;
        }
        char[] charArray = new StringBuffer(charStr).reverse().toString().toCharArray();
        boolean tempBtn = true;
        charStr = "";
        for (char str : charArray) {
            if (tempBtn) {
                String valueOf = String.valueOf(str);
                if (valueOf.matches("[a-z]+")) {
                    String charBigNext = getCharMinNext(valueOf);
                    if (!charBigNext.equals("a")) {
                        tempBtn = false;
                    } else {
                        charBigNext = "0";
                    }
                    charStr += charBigNext;
                } else if (valueOf.matches("[A-Z]+")) {
                    String charBigNext = getCharBigNext(valueOf);
                    if (charBigNext.equals("A")) {
                        charBigNext = "a";
                    }
                    tempBtn = false;
                    charStr += charBigNext;
                } else {
                    String charBigNext = getNumNext(valueOf);
                    if (charBigNext.equals("0")) {
                        charBigNext = "A";
                    }
                    tempBtn = false;
                    charStr += charBigNext;
                }
            } else {
                charStr += str;
            }
        }
        return new StringBuffer(charStr).reverse().toString();
    }

    /**
     * 取得字串数字与字母小写的下个字串
     * 
     * @param charStr 循环字串
     * @return
     */
    private static String getNumAndCharMin(String charStr) {
        if (charStr == null) {
            return charStr;
        }
        char[] charArray = new StringBuffer(charStr).reverse().toString().toLowerCase().toCharArray();
        boolean tempBtn = true;
        charStr = "";
        for (char str : charArray) {
            if (tempBtn) {
                String valueOf = String.valueOf(str);
                if (valueOf.matches("[a-z]+")) {
                    String charBigNext = getCharMinNext(valueOf);
                    if (!charBigNext.equals("a")) {
                        tempBtn = false;
                    } else {
                        charBigNext = "0";
                    }
                    charStr += charBigNext;
                } else {
                    String charBigNext = getNumNext(valueOf);
                    if (charBigNext.equals("0")) {
                        charBigNext = "a";
                    }
                    tempBtn = false;
                    charStr += charBigNext;
                }
            } else {
                charStr += str;
            }
        }
        return new StringBuffer(charStr).reverse().toString();
    }

    /**
     * 取得字串数字与字母大写的下个字串
     * 
     * @param charStr 循环字串
     * @return
     */
    private static String getNumAndCharBig(String charStr) {
        if (charStr == null) {
            return charStr;
        }
        char[] charArray = new StringBuffer(charStr).reverse().toString().toUpperCase().toCharArray();
        boolean tempBtn = true;
        charStr = "";
        for (char str : charArray) {
            if (tempBtn) {
                String valueOf = String.valueOf(str);
                if (valueOf.matches("[A-Z]+")) {
                    String charBigNext = getCharBigNext(valueOf);
                    if (!charBigNext.equals("A")) {
                        tempBtn = false;
                    } else {
                        charBigNext = "0";
                    }
                    charStr += charBigNext;
                } else {
                    String charBigNext = getNumNext(valueOf);
                    if (charBigNext.equals("0")) {
                        charBigNext = "A";
                    }
                    tempBtn = false;
                    charStr += charBigNext;
                }
            } else {
                charStr += str;
            }
        }
        return new StringBuffer(charStr).reverse().toString();
    }

    /**
     * 取得字串数字下个字串
     * 
     * @param charStr 循环字串
     * @return
     */
    private static String getNumNext(String charStr) {
        boolean single = false;
        if (charStr.length() == 1) {
            single = true;
        }
        int parseInt = Integer.parseInt(charStr);
        parseInt++;
        // 单数如里参与循环那么不能大于九，过大就为零
        if (single && parseInt > 9) {
            parseInt = 0;
        }
        charStr = String.valueOf(parseInt);
        return charStr;
    }

    /**
     * 取得字串字母大写的下个字串
     * 
     * @param charStr 循环字串
     * @return
     */
    private static String getCharBigNext(String charStr) {
        if (charStr == null) {
            return charStr;
        }
        char[] charArray = new StringBuffer(charStr).reverse().toString().toUpperCase().toCharArray();
        boolean tempBtn = true;
        charStr = "";
        for (char str : charArray) {
            int ascStr = ((int) str) + 1;
            if (tempBtn && ascStr <= CharBigThresholdVal) {
                charStr += (char) ascStr;
                tempBtn = false;
            } else if (tempBtn && ascStr > CharBigThresholdVal) {
                charStr += "A";
            } else {
                charStr += str;
            }
        }

        return new StringBuffer(charStr).reverse().toString();
    }

    /**
     * 取得字串字母小写的下个字串
     * 
     * @param charStr 循环字串
     * @return
     */
    private static String getCharMinNext(String charStr) {
        if (charStr == null) {
            return charStr;
        }
        char[] charArray = new StringBuffer(charStr).reverse().toString().toLowerCase().toCharArray();
        boolean tempBtn = true;
        charStr = "";
        for (char str : charArray) {
            int ascStr = ((int) str) + 1;
            if (tempBtn && ascStr <= CharMinThresholdVal) {
                charStr += (char) ascStr;
                tempBtn = false;
            } else if (tempBtn && ascStr > CharMinThresholdVal) {
                charStr += "a";
            } else {
                charStr += str;
            }
        }

        return new StringBuffer(charStr).reverse().toString();
    }

    /**
     * 生成n个随机数
     * 
     * @param n     生成随机数的个数
     * @param scope 生成随数的范围值
     * @return
     */
    public static ArrayList getDiffNO(int n, int scope) {
        ArrayList list = new ArrayList<>();

        Random random = new Random();
        boolean[] bool = new boolean[n];

        int num = 0;
        for (int i = 0; i < n; i++) {
            do {
                num = random.nextInt(scope);
            } while (bool[i]);
            bool[i] = true;
            list.add(num);
        }
        return list;
    }

    /**
     * 生成n 个概率值的数组，且总合数等给总合取值数
     * 
     * @param num         生成的概率数据个ovt
     * @param probability 概率数
     * @param rangeVal    总合取值数
     * @return
     */
    public static List<Integer> getProbabilityCombination(Integer num, double probability, Integer rangeVal) {
        List<Integer> resList = new ArrayList<>();
        boolean run = true; //循环开关
        Integer steepNum = (int) (rangeVal * probability); //当前最大取值
        float errorVal = (float) (1%rangeVal);//计算偏差值

        //当前最大值不能小于0 小于则值返回总合取值数
        if (steepNum == 0) {
            resList.add(rangeVal);
            return resList;
        }
        resList.add(steepNum);
        do {
            if (num - 1 != 0) {
                resList.addAll(getProbabilityCombination(num - 1, probability, (rangeVal - steepNum)));
            }
            int sum = resList.stream().mapToInt(Integer::intValue).sum(); //求出数组中的所有总合数
            int magnificationTotal = rangeVal << num; //放大最大总合数据num倍
            int tempMagnification = 0;
            if (resList.size() < num) {
                continue;
            }
            for (int i = 1; i <= num; i++) {
                tempMagnification += resList.get(i - 1) * i;
            }
            //判断是否满足取值的条件，满足就退出
            if ((sum == rangeVal && (tempMagnification / magnificationTotal) >= (probability-errorVal))
                    || ((num / rangeVal) <= (probability+errorVal))) {
                run = false;
            } else {
                steepNum--;
            }
        } while (run);
        return resList;
    }

}
